﻿using ClumsyWords.Portable.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace ClumsyWords.Portable.ViewModel
{
    public class SearchService
    {
        public static bool TryParseXMLResponse(string responseText, Func<TermProperties, PartOfSpeech> getKeyFunc, out string term, out List<CommonGroup<TermProperties>> results)
        {
            results = new List<CommonGroup<TermProperties>>();
            term = String.Empty;
            if (responseText == String.Empty) return false;

            XDocument doc = XDocument.Parse(responseText);
            if (doc.Element("results").Elements("results") != null)
            {
                //Composing the search result from xml
                term = doc.Element("results").Elements("result").First().Element("term").Value.ToString();
                List<TermProperties> termProperties = (from _props in doc.Element("results").Elements("result")
                           select new TermProperties
                           {
                               Term = _props.Element("term").Value.ToString(),
                               Definition = _props.Element("definition").Value.ToString(),
                               Example = _props.Element("example").Value.ToString(),
                               PartOfSpeech = SearchService.PartOfSpeechStringConversion(_props.Element("partofspeech").Value.ToString())
                           }).ToList();

                results = (from tp in termProperties
                          group tp by getKeyFunc(tp) into g
                          orderby g.Key
                          select new CommonGroup<TermProperties>(g.Key.ToString(), g.Key.ToString(), g, true)).ToList();

                return true;
            }
            return false;
        }

        public static async Task<List<CommonGroup<TermProperties>>> GetSearchResultAsync(string url)
        {
            HttpClient client = new HttpClient();

            HttpResponseMessage response = await client.GetAsync(url);
            string responseText = await response.Content.ReadAsStringAsync();
            
            List<CommonGroup<TermProperties>> termProps;
            string term;

            if (SearchService.TryParseXMLResponse(responseText, p => p.PartOfSpeech, out term, out termProps))
                return termProps;

            return new List<CommonGroup<TermProperties>>();
        }

        private static PartOfSpeech PartOfSpeechStringConversion(string key)
        {
            const string NounString1 = "noun";
            const string NounString2 = ""; //idk
            const string PronounString = "pronoun";
            const string AdjectiveString1 = "adj";
            const string AdjectiveString2 = "adjective";
            const string VerbString1 = "verb";
            const string AdverbString1 = "adv";
            const string AdverbString2 = "adverb";
            const string PrepositionString1 = "prep";
            const string PrepositionString2 = "preposition";
            const string ConjunctionString1 = "conjunction";
            const string InterjectionString1 = "interjection";

            switch (key.ToLower())
            {
                case NounString1:
                case NounString2:
                    return PartOfSpeech.noun;
                case PronounString:
                    return PartOfSpeech.pronoun;
                case AdjectiveString1:
                case AdjectiveString2:
                    return PartOfSpeech.adjective;
                case AdverbString1:
                case AdverbString2:
                    return PartOfSpeech.adverb;
                case VerbString1:
                    return PartOfSpeech.verb;
                case PrepositionString1:
                case PrepositionString2:
                    return PartOfSpeech.preposition;
                case ConjunctionString1:
                    return PartOfSpeech.conjunction;
                case InterjectionString1:
                    return PartOfSpeech.interjection;
                default: return PartOfSpeech.other;
            }
        }
    }
}
